#include "Thread.hpp"
#include "RingQueue.hpp"
#include "Task.hpp"
#include <ctime>

using namespace yss;
using RingQueue_t = RingQueue<Task>;

void ProductorCore(RingQueue_t &rq, const string& name)
{
    while(true)
    {
        Task t;
        rq.Enqueue(t);
        cout << "Productor: " << " [" << name << "]" << endl;
    }
}
void ConsumerCore(RingQueue_t &rq, const string& name)
{
    while(true)
    {
        sleep(2);
        Task t;
        rq.Pop(t);
        cout << "Consumer: " << " [" << name << "]" << endl;
        t.Download();
    }
}

void SatrtComm(vector<Thread<RingQueue_t>> *threads, int num, RingQueue_t &rq, func_t<RingQueue_t> func)
{
    for(int i=0; i<num; i++)
    {
        string name = "thread-" + to_string(i+1);
        threads->emplace_back(func, rq, name);
        // threads->back().Start();// 不能这样写，多个线程并发时，下标会位移，
        // 即back()会变化，start的就不是原来的了
    }
}

void StartProductor(vector<Thread<RingQueue_t>> *threads, int num, RingQueue_t &rq)
{
    SatrtComm(threads, num, rq, ProductorCore);
}
void StartConsumer(vector<Thread<RingQueue_t>> *threads, int num, RingQueue_t &rq)
{
    SatrtComm(threads, num, rq, ConsumerCore);
}

void StartAllThread(vector<Thread<RingQueue_t>> &threads)
{
    for(auto &t : threads)
    {
        t.Start();
    }
}

void WaitAll(vector<Thread<RingQueue_t>> &threads)
{
    for(auto &t : threads)
    {
        t.Join();
    }
}

int main()
{
    RingQueue_t *rq = new RingQueue_t(10);
    vector<Thread<RingQueue_t>> threads;
    StartProductor(&threads, 2, *rq);
    StartConsumer(&threads, 3, *rq);
    StartAllThread(threads);
    WaitAll(threads);//
    return 0;
}